package PrjHttpWs

import (
	"dgo/goutils/utils"
	"errors"
	"fmt"
	"gitee.com/ymofen/gobase/golog"
	"gitee.com/ymofen/supervalue"
	"net/http"
	"os"
	"strings"

	"golang.org/x/net/websocket"
)

type WsSvrConn struct {
	channelMap        utils.GSyncMapGroup
	owner             *WsHttpService
	conn              *websocket.Conn
	trans_attach_info bool
	remoteAddr        string
	lastWarning       string
}

func NewWsSvrConn(conn *websocket.Conn, owner *WsHttpService) *WsSvrConn {
	rval := &WsSvrConn{
		conn:  conn,
		owner: owner,
	}
	if conn.Request() != nil {
		rval.remoteAddr = conn.Request().RemoteAddr
	} else {
		rval.remoteAddr = conn.RemoteAddr().String()
	}
	return rval
}

func (this *WsSvrConn) String() string {
	return fmt.Sprintf("%s", this.remoteAddr)
}

/*
**

	收到订阅通道的数据,进行发送
*/
func (this *WsSvrConn) onChannelRecv(sender interface{}, channelid string, subscribeid interface{}, data interface{}, tag interface{}, isBreak *bool) bool {
	conn := this.conn

	if conn == nil { // 连接断开或者不存在
		return true
	}
	var buf []byte
	if str, ok := data.(string); ok {
		buf = []byte(str)
	} else if json, ok := data.(*wrapper.SuperValue); ok {
		if this.trans_attach_info {
			if from, ok1 := sender.(*WsSvrConn); ok1 {
				info := json.ForceByPath("info")
				info.SetKeyValue("from-addr", from.remoteAddr)
			}
		}

		buf = json.AsJSONBytes(false)
	} else if b1, ok := data.([]byte); ok {
		buf = b1
	} else {
		fmt.Fprintf(os.Stderr, "[WsSvrConn.onChannelRecv]未知的分发数据:%v\r\n", data)
		return false
	}

	err := SendWsMessage(this.conn, WS_MESSAGE_TEXT, buf)
	if err != nil {
		this.lastWarning = fmt.Sprintf("[%s]发送数据出现异常:%s", utils.NowString(), err.Error())
	} else {
		owner := this.owner
		if owner != nil {
			m := owner.monitor_SendSize
			if m != nil {
				m.Delta(int64(len(buf)))
			}
		}
	}
	return true
}

func (this *WsSvrConn) onClose() {
	owner := this.owner
	if owner != nil {
		this.channelMap.Range(func(key, value interface{}) bool {
			channelid := key.(string)
			owner.sc.UnsubscribeChannel(channelid, this)
			return true
		})
	}

	golog.Debugf("[断线][%s]", this.remoteAddr)
	this.conn = nil
}

func (this *WsSvrConn) Request() *http.Request {
	conn := this.conn
	if conn == nil {
		return nil
	}
	return this.conn.Request()
}

func (this *WsSvrConn) SendV(data interface{}) error {
	if str, ok := data.(string); ok {
		return SendWsMessage(this.conn, WS_MESSAGE_TEXT, []byte(str))
	} else if json, ok := data.(*wrapper.SuperValue); ok {
		return SendWsMessage(this.conn, WS_MESSAGE_TEXT, json.AsJSONBytes(false))
	} else if buf, ok := data.([]byte); ok {
		return SendWsMessage(this.conn, WS_MESSAGE_TEXT, buf)
	} else {
		return fmt.Errorf("未知的发送数据:%v", data)
	}
}

func (this *WsSvrConn) SendKVS(kvs ...interface{}) error {
	l := len(kvs)
	if l == 0 {
		return errors.New("没有需要发送的数据")
	}
	if l == 1 {
		return this.SendV(kvs[0])
	}

	json := wrapper.NewSVObject()
	json.SetKeyValues(kvs...)
	return this.SendV(json)
}

func (this *WsSvrConn) SubscribleChannel(channels string) int {
	r := 0
	strs := strings.Split(channels, ",")
	for _, str := range strs {
		channelid := utils.Trim(str)
		if len(channelid) == 0 {
			continue
		}
		itm := this.channelMap.Get(channelid, nil)
		if itm == nil {
			//id := utils.RandHexString(24)
			golog.Debugf("[订阅]通道:[%s], %s", channelid, this.remoteAddr)
			this.owner.sc.SubscribeChannel(channelid, this, this.onChannelRecv)
			this.channelMap.Set(channelid, this)
			r++
		}
	}
	return r
}

func (this *WsSvrConn) UnsubscribleChannel(channels string) int {
	r := 0
	strs := strings.Split(channels, ",")
	for _, str := range strs {
		channelid := utils.Trim(str)
		if len(channelid) == 0 {
			continue
		}
		itm := this.channelMap.Get(channelid, nil)
		if itm != nil {
			//id := itm.(string)
			golog.Debugf("[取消订阅]通道:[%s], %s", channelid, this.remoteAddr)
			this.owner.sc.UnsubscribeChannel(channelid, this)
			this.channelMap.Remove(channelid)
			r++
		}
	}
	return r
}
